import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:osc/res/dimens.dart';
import 'package:osc/ui/widgets/image_loader.dart';
import 'package:flutter_swiper/flutter_swiper.dart';


class GalleryPage extends StatefulWidget{
  final List<String> imageUrls;
  final int index;
  GalleryPage({@required this.imageUrls, this.index = 0});

  @override
  State<StatefulWidget> createState() {
    return new GalleryPageState(imageUrls, index);
  }
}

class GalleryPageState extends State<GalleryPage> with SingleTickerProviderStateMixin{
  final List<String> imageUrls;
  int index;

  GalleryPageState(this.imageUrls, this.index);

  double height = 0;
  int itemCount = 0;

  AnimationController _controller;
  Animation<Offset> _animation;
  Offset _offset = Offset.zero;
  double _scale = 1.0;
  Offset _normalizedOffset;
  double _previousScale;
  double _kMinFlingVelocity = 600.0;


  @override
  void initState() {
    super.initState();
    itemCount = imageUrls?.length ?? 0;

    _controller = AnimationController(vsync: this);
    _controller.addListener(() {
      setState(() {
        _offset = _animation.value;
      });
    });
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if(height == 0){
      height = ScreenUtil.getScreenH(context);
    }

    return Container(
      color: Colors.white70,
      height: height,
      child: Swiper(
        onTap: (int index){
          Navigator.pop(context);
        },
        onIndexChanged: (int index){
          this.index = index;
          _scale = 1.0;
          _offset = Offset.zero;
          refreshView();
        },
        itemBuilder: (BuildContext context, int index){
          return GestureDetector(
            onDoubleTap: (){
              if(_scale != 1){
                _scale = 1.0;
                _offset = Offset.zero;
              }
              refreshView();
            },
            onScaleStart: _handleOnScaleStart,
            onScaleUpdate: _handleOnScaleUpdate,
            onScaleEnd: _handleOnScaleEnd,
            child: ClipRRect(
              child: Transform(
                transform: Matrix4.identity()..translate(_offset.dx, _offset.dy)
                  ..scale(_scale),
                child: ImageLoader(
                  url: imageUrls.elementAt(index),
                  fit: BoxFit.contain,
                  filterQuality: FilterQuality.high,
                ),
              ),
            ),
          );
        },
        index: index,
        itemCount: itemCount,
        itemHeight: height,
        autoplay: false,
        loop: false,
        pagination: SwiperPagination(
            alignment: Alignment.bottomCenter,
            builder: DotSwiperPaginationBuilder(
              color: Colors.white,
              activeColor: Colors.green,
              size: Dimens.view_radius_size_normal,
              activeSize: Dimens.view_radius_size_normal,
            )
        ),
      ),
    );
  }

  Offset _clampOffset(Offset offset) {
    final Size size = context.size;
    // widget的屏幕宽度
    final Offset minOffset = Offset(size.width, size.height) * (1.0 - _scale);
    // 限制他的最小尺寸
    return Offset(
        offset.dx.clamp(minOffset.dx, 0.0), offset.dy.clamp(minOffset.dy, 0.0));

  }

  void _handleOnScaleStart(ScaleStartDetails details) {
    setState(() {
      _previousScale = _scale;
      _normalizedOffset = (details.focalPoint - _offset) / _scale;
      // 计算图片放大后的位置
      _controller.stop();
    });
  }

  void _handleOnScaleUpdate(ScaleUpdateDetails details) {
    setState(() {
      _scale = (_previousScale * details.scale).clamp(1.0, 3.0);
      // 限制放大倍数 1~3倍
      _offset = _clampOffset(details.focalPoint - _normalizedOffset * _scale);
      // 更新当前位置
    });
  }

  void _handleOnScaleEnd(ScaleEndDetails details) {
    final double magnitude = details.velocity.pixelsPerSecond.distance;
    if (magnitude < _kMinFlingVelocity) return;
    final Offset direction = details.velocity.pixelsPerSecond / magnitude;
    // 计算当前的方向
    final double distance = (Offset.zero & context.size).shortestSide;
    // 计算放大倍速，并相应的放大宽和高，比如原来是600*480的图片，放大后倍数为1.25倍时，宽和高是同时变化的
    _animation = _controller.drive(Tween<Offset>(
        begin: _offset, end: _clampOffset(_offset + direction * distance)));
    _controller
      ..value = 0.0
      ..fling(velocity: magnitude / 1000.0);
  }

  refreshView(){
    if(mounted){
      setState(() {

      });
    }
  }
}